package com.gtan.hogpen.benchmark

import com.alibaba.druid.pool.DruidDataSource
import java.util.concurrent.CountDownLatch
import scala.Exception
import javax.sql.DataSource
import java.text.NumberFormat

object DruidBenchmark extends TypesafeConfig{
  val Pass = 1000
  val totalLatch = new CountDownLatch(Pass)

  def main(args: Array[String]) {
    val initialSize = 10
    val minPoolSize = 10
    val maxPoolSize = 50
    val maxActive = 50

    val dataSource = new DruidDataSource()

    dataSource.setInitialSize(initialSize)
    dataSource.setMaxActive(maxActive)
    dataSource.setMinIdle(minPoolSize)
    dataSource.setMaxIdle(maxPoolSize)
    dataSource.setPoolPreparedStatements(true)
    dataSource.setDriverClassName(config.getString("datasource.driverClass"))
    dataSource.setUrl(config.getString("datasource.url"))
    dataSource.setPoolPreparedStatements(true)
    dataSource.setUsername(config.getString("datasource.username"))
    dataSource.setPassword(config.getString("datasource.password"))
    dataSource.setValidationQuery("SELECT 1")
    dataSource.setTestOnBorrow(false)


    val startMillis = System.currentTimeMillis()
    for (i <- 0 until Pass) {
      p0(dataSource, "druid", 50)
    }
    totalLatch.await()
    val millis = System.currentTimeMillis() - startMillis

    System.out.println(s"total: $millis")
  }


  def p0(dataSource: DataSource, name: String, threadCount: Int) {
    val startLatch = new CountDownLatch(1)
    val endLatch = new CountDownLatch(threadCount)
    val dumpLatch = new CountDownLatch(1)
    val LOOP_COUNT = Pass * 1 * 1 / threadCount
    val threads = Array.fill(threadCount) {
      val thread = new Thread {
        override def run() {
          try {
            startLatch.await()

            for (i <- 0 to LOOP_COUNT) {
              val conn = dataSource.getConnection
              conn.close()
            }
          } catch {
            case ex: Throwable => ex.printStackTrace()
          }
          endLatch.countDown()

          //          try {
          //            dumpLatch.await()
          //          } catch {
          //            case e: InterruptedException => e.printStackTrace()
          //          }
        }
      }
      thread.start()
    }
    val startMillis = System.currentTimeMillis()

    //    val startYGC = TestUtil.getYoungGC
    //    val startFullGC = TestUtil.getFullGC
    startLatch.countDown()
    endLatch.await()

    //    val blockedCount = 0
    //    val waitedCount = 0
    //    for (threadInfo <- threadInfoArray) {
    //      blockedCount += threadInfo.getBlockedCount
    //      waitedCount += threadInfo.getWaitedCount
    //    }

    val millis = System.currentTimeMillis() - startMillis
    //    val ygc = TestUtil.getYoungGC - startYGC
    //    val fullGC = TestUtil.getFullGC - startFullGC

    println(s"thread $threadCount $name millis : ${NumberFormat.getInstance.format(millis)}; " +
      //      s"YGC $ygc FGC $fullGC " +
      //      s"blocked ${NumberFormat.getInstance.format(blockedCount)} waited ${NumberFormat.getInstance.format(waitedCount)} " +
      //      s"physicalConn ${phisicalConnStat.get}"
      "")
    totalLatch.countDown()
  }
}
